from django.template import Context, Template, loader
from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.conf import settings
from xml.dom.minidom import Document
import datetime, os, zipfile, shutil, re
from main import models, forms
from main.models import STATUS as ST

#####################################################################################
#Page views
#####################################################################################
def serve_home(request):
    return serve_page_generic(request, 'home', {}, 'Home', 0)

def serve_create_profile(request):
    if request.method == 'GET':
        the_form = forms.personForm()
    if request.method == 'POST':
        form = forms.personForm(request.POST)
        if form.is_valid():
            person = form.save(commit=False)
            #create system user
            user = User(username=person.email, first_name=person.name, last_name=person.surname)
            user.set_password(person.password)
            user.save(force_insert=True)
            #continue saving person
            person.user = user
            person.key = generate_key()
            person.save(force_insert=True)
            #login as a new user
            logout(request)
            auser = authenticate(username=person.email, password=person.password)
            login(request, auser)
            return HttpResponseRedirect('/')
        else:
            the_form = forms.personForm(request.POST)
    return serve_page_generic(request, 'create-profile', {'form':the_form}, 'Create profile')

@login_required
def serve_create_dataset(request):
    status = 'none'
    if request.method == 'GET':
        form = forms.datasetForm()
    if request.method == 'POST':
        form = forms.datasetForm(request.POST, request.FILES)
        if form.is_valid():
            dataset = form.save(commit=False)
            dataset.person = request.user.get_profile()
            dataset.save()
            handle = handle_dataset(dataset, request.FILES['data'])
            if handle:
                status = 'created'
                form = forms.datasetForm()
            else:
                status = 'failed'
    return serve_page_generic(request, 'create-dataset', {'form':form, 'status_'+status:True}, 'Create dataset')

@login_required
def serve_create_ticket(request):
    if request.method == 'GET':
        form=forms.ticketForm()
    if request.method == 'POST':
        form = forms.ticketForm(request.POST)
        if form.is_valid():
            the_ticket = form.save(commit=False)
            the_ticket.person = request.user.get_profile()
            the_ticket.save(force_insert=True)
            return HttpResponseRedirect('/view/tasks')
        else:
            form=forms.ticketForm(request.POST)
    return serve_page_generic(request, 'create-ticket', {'form':form}, 'Create ticket')

def serve_view_users(request):
    context={}
    context['pack']=models.person.objects.all().order_by('-cpu_flops')[:10]
    return serve_page_generic(request, 'view-users', context, 'View users',1)

def serve_view_nodes(request):
    context={}
    context['pack']=models.node.objects.all().order_by('-id')[:10]
    return serve_page_generic(request, 'view-nodes', context, 'View nodes',2)

def serve_view_tasks(request):
    context={}
    context['loggedin']=request.user.is_authenticated()
    context['pack']=models.ticket.objects.all().order_by('-id')[:10]
    return serve_page_generic(request, 'view-tasks', context, 'View tasks',3)

@login_required
def serve_view_result(request,id):
    result = models.ticket.objects.get(id=id)
    if result.person == request.user.get_profile():
        f = open('/home/sol/trash/result','w')
        f.write(result.result_data)
        f.close()
        response = HttpResponse(result.result_data, mimetype='text/plain')
        response['Content-Disposition'] = 'attachment; filename=result.txt'
        response.status_code = 200
        return response

@login_required
def serve_delete_dataset(request,id):
    status = ''
    try:
        dataset = models.dataset.objects.get(id=id)
        if dataset.person == request.user.get_profile():
            path = settings.ROOT+'trunk/data/'+str(dataset.person.id)+'/'+str(dataset.id)+'.zip'
            os.remove(path)
            dataset.delete()
            status = 'Deleted'
        else:
            status = 'Dataset doesn\'t belong to you.'
    except:
        status = 'Dataset wasn\'t found.'
    return serve_page_generic(request, 'delete', {'status':status}, 'Delete dataset')

#####################################################################################
#AJAX views
#####################################################################################
def ajax_serve_news(request, the_id):
    HttpResponse.status_code=200
    item = models.new.objects.get(id=the_id)
    return tpl("ajax/news.html", {'item':item})

def ajax_serve_stats(request, the_id):
    HttpResponse.status_code=200
    profile = models.person.objects.get(id=the_id)
    return tpl("ajax/stats.html", {'profile':profile})

def ajax_serve_nodes(request, the_id):
    HttpResponse.status_code=200
    nodes = models.node.objects.filter(person = the_id)
    return tpl("ajax/nodes.html", {'pack':nodes})

def ajax_serve_results(request, the_id):
    HttpResponse.status_code=200
    tickets = models.ticket.objects.filter(person = the_id, completed = True).order_by('-id')[:5]
    return tpl("ajax/results.html", {'pack':tickets})

def ajax_serve_datasets(request, the_id):
    HttpResponse.status_code=200
    datasets = models.dataset.objects.filter(person = the_id)
    return tpl("ajax/datasets.html", {'pack':datasets})

def ajax_update_banner_stats(request):
    HttpResponse.status_code=200
    context = {}
    context['nodes'] = models.node.objects.count()
    context['tasks'] = models.ticket.objects.filter(completed=False).count()
    context['units'] = models.unit.objects.count()
    return tpl("ajax/bannerstats.html", context)

def ajax_update_banner_flops(request):
    HttpResponse.status_code=200
    flops = models.total_flops() * 10**6 or 0
    power = 0
    while flops >= 10:
        flops/=10
        power+=1
    flops = '%.3f' % flops
    return tpl("ajax/bannerflops.html", {'flops':flops, 'power':power})

#####################################################################################
#Generic page views
#####################################################################################
def serve_page_generic(request, template, content, title='No title', menuitem=-1):
    outer_context = {}
    outer_context['title'] = title
    outer_context['content'] = itpl('page/'+template+'.html',content)
    outer_context['news'] = get_news_list()
    outer_context['menuitem'+str(menuitem)] = True
    if request.user.is_authenticated():
        try:
            outer_context['profile'] = request.user.get_profile()
        except:
            pass
    if request.method == 'GET' and request.GET.has_key('error'):
        outer_context['error'+request.GET['error']] = True
    return tpl("base.html", Context(outer_context))

def serve_static_page(request,path):
    title = path.replace('-',' ')
    title = title[0].upper() + title[1:]
    return serve_page_generic(request, 'static/'+path, {}, title, 0)

def ajax_serve_static_page(request,path):
    return tpl('ajax/static/'+path+'.html')

def get_news_list():
    news = models.new.objects.all().order_by('-id')[:5]
    return news

#####################################################################################
#Secondary functions
#####################################################################################
def tpl(name, context={}):
    return HttpResponse(loader.get_template(name).render(Context(context)))

def itpl(name, context={}):
    return loader.get_template(name).render(Context(context))

def do_login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect('/')
    return HttpResponseRedirect('/?error=1')

def do_logout(request):
    try:
        logout(request)
    except:
        pass
    return HttpResponseRedirect('/')

def generate_key():
    import uuid
    return str(uuid.uuid4())+'-'+str(uuid.uuid4())

def handle_dataset(dataset, data):
    #create user/dataset directory
    root = settings.ROOT+'trunk/data/'+str(dataset.person.id)+'/'
    if not os.path.exists(root):
        os.mkdir(root)
    path = root+str(dataset.id)+'.zip'
    #recollect uploaded files
    destination = open(path, 'wb+')
    for chunk in data.chunks():
        destination.write(chunk)
    destination.close()
    #validate file
    try:
        z = zipfile.ZipFile(path)
        zfilelist = z.namelist()
        z.close()
    except:
        return False
    dataset.filesize = os.stat(path).st_size
    if not dataset.filesize:
        return False
    dataset.save()
    #all done
    return True
#####################################################################################
# Error views
#####################################################################################
def stub(request):
    return tpl('page/stub.html')

def serve_404(request):
    return tpl('page/404.html')